﻿using System;
using System.Linq;
using System.Web.Caching;
using Microsoft.Practices.ServiceLocation;
using Pap.Core.CronJobs;
using Pap.Data;
using Pap.Data.Abstraction.Utils;
using Pap.Services;
using Pap.Services.WorkflowEngine;

namespace Pap.Web.Utils.CronJobs
{
    /// <summary>
    /// 
    /// </summary>
    public class StumbledLoansCronJobs : ICronJob
    {
        /// <summary>
        /// 
        /// </summary>
        IWorkflowService _WfService;
        /// <summary>
        /// 
        /// </summary>
        ILoanRepository _LoanRepository;
        /// <summary>
        /// Initializes a new instance of the <see cref="StumbledLoansCronJobs"/> class.
        /// </summary>
        /// <param name="wfService">The wf service.</param>
        /// <param name="loanRepository">The loan repository.</param>
        public StumbledLoansCronJobs(IWorkflowService wfService, ILoanRepository loanRepository)
        {
            _WfService = wfService;
            _LoanRepository = loanRepository;
        }

        #region ICronJob Members

        /// <summary>
        /// Gets the sliding time.
        /// </summary>
        public TimeSpan SlidingTime
        {
            get { return TimeSpan.FromDays(1); }
        }

        /// <summary>
        /// Gets the name of the job.
        /// </summary>
        /// <value>
        /// The name of the job.
        /// </value>
        public string JobName
        {
            get { return "Stumbling Loans"; }
        }

        /// <summary>
        /// Executes this instance.
        /// </summary>
        public void Execute()
        {
            using (IUnitOfWork trans = ServiceLocator.Current.GetInstance<IUnitOfWork>())
            {
                var currentPaymentloans = _LoanRepository.FindCustomerLoans(loan => _WfService.GetInStep(Steps.PaymentList).Contains(loan.LoanID));

                var currentloansExecutions = currentPaymentloans.Select(
                    loan => loan.LoanExecutionLst.Where(loanex => loanex.LoanExecutionStatus).OrderBy(LoanEx => LoanEx.ExecutionDate).
                        LastOrDefault()).Where(ex => ex != null);

                var firstDuedInstallment = currentloansExecutions.Select(loanEx => loanEx.LoanExecutionInstallmentsLst.Where(inst => !inst.IsPaid && inst.InstallmentDate.Date <= DateTime.Today.Date).OrderBy(
                    inst => inst.InstallmentDate).FirstOrDefault()).Where(inst => inst != null);

                var stumbledLoansIDs = firstDuedInstallment.Where(
                inst => DateTime.Now.Subtract(inst.InstallmentDate).Days > 90).Select(inst => inst.LoanExecution.LoanID).Select(guid => (Nullable<Guid>)guid);



                var loansStepInstances = _WfService.GetInstancesInStep(Steps.PaymentList).Where(stepInst => stumbledLoansIDs.Contains(stepInst.wfProcessInstance.EntityID));

                loansStepInstances.ForEach(step =>
                    {
                        _WfService.Move(ActionTypes.Stumble, step.ProcessInstanceID, step.UserID, string.Empty, null);
                    });

                trans.Commit();
            }
        }

        #endregion
    }
}
